/* Copyright (c) 2008 Google Inc.
*  Copyright (c) 2009 Pierre Henri Kuate.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using org.opensocial.data;
namespace org.opensocial.client
{
    /// <summary> An object which represents the response from an OpenSocial container after
    /// one or more requests for data. Objects should not be instantiated directly
    /// by clients -- instead, instances are generated by calling the send method
    /// of OpenSocialBatch objects. This class simply contains wrapper methods
    /// which parse a particular response item and return the appropriate
    /// OpenSocialObject type.
    /// </summary>
    /// <author>  Jason Cooper
    /// </author>
    public class OpenSocialResponse
    {
        private readonly System.Collections.Generic.IDictionary<string, string> items;

        public OpenSocialResponse()
        {
            items = new System.Collections.Generic.Dictionary<string, string>();
        }

        /// <summary> Retrieves and parses the JSON-encoded response item with the passed ID and
        /// returns the parsed item as an Person object.
        /// </summary>
        /// <param name="id">ID of the response item to parse
        /// </param>
        /// <throws>  OpenSocialRequestException </throws>
        /// <throws>  JSONException </throws>
        /// <throws>  IllegalAccessException </throws>
        /// <throws>  InstantiationException </throws>
        public data.Person getItemAsPerson(string id)
        {
            string item = items[id];

            return OpenSocialJsonParser.parseAsPerson(item);
        }

        /// <summary> Retrieves and parses the JSON-encoded response item with the passed ID and
        /// returns the parsed item as a List of Person objects.
        /// </summary>
        /// <param name="id">ID of the response item to parse
        /// </param>
        /// <param name="useRpc"></param>
        /// <throws>  OpenSocialRequestException </throws>
        /// <throws>  JSONException </throws>
        public Response<Person> getItemAsPersonCollection(string id, bool useRpc)
        {
            string item = items[id];

            return OpenSocialJsonParser.parseAsPersonCollection(item, useRpc);
        }

        /// <summary> Retrieves and parses the JSON-encoded response item with the passed ID and
        /// returns the parsed item as an AppData object.
        /// </summary>
        /// <param name="id">ID of the response item to parse
        /// </param>
        /// <throws>  OpenSocialRequestException </throws>
        /// <throws>  JSONException </throws>
        public Response<AppData> getItemAsAppData(string id)
        {
            string item = items[id];

            return OpenSocialJsonParser.parseAsAppData(item);
        }

        /// <summary> Retrieves and parses the JSON-encoded response item with the passed ID and
        /// returns the parsed item as a List of Person objects.
        /// </summary>
        /// <param name="id">ID of the response item to parse
        /// </param>
        /// <param name="useRpc"></param>
        /// <throws>  OpenSocialRequestException </throws>
        /// <throws>  JSONException </throws>
        public Response<Activity> getItemAsActivityCollection(string id, bool useRpc)
        {
            return OpenSocialJsonParser.parseAsActivityCollection(items[id], useRpc);
        }

        public Album getItemAsAlbum(string id, bool useRpc)
        {
            return getItemAsObject<Album>(id, "album");
        }

        public Response<Album> getItemAsAlbumCollection(string id, bool useRpc)
        {
            return getItemAsCollection<Album>(id, useRpc, "album");
        }

        public MediaItem getItemAsMediaItem(string id, bool useRpc)
        {
            return getItemAsObject<MediaItem>(id, "mediaItem");
        }

        public Response<MediaItem> getItemAsMediaItemCollection(string id, bool useRpc)
        {
            return getItemAsCollection<MediaItem>(id, useRpc, "mediaItem");
        }

        public Response<MediaItemComment> getItemAsMediaitemCommentsCollection(string id, bool useRpc)
        {
            return getItemAsCollection<MediaItemComment>(id, useRpc, "entry");
        }

        public StatusMood getItemAsStatusMood(string id, bool useRpc)
        {
            return getItemAsObject<StatusMood>(id, "statusMood");
        }

        public Response<StatusMood> getItemAsStatusMoodCollection(string id, bool useRpc)
        {
            if (id.CompareTo("@supportedMood") == 0)
            {
                Response<StatusMood> smList = new Response<StatusMood>();
                foreach (string moodId in items.Keys)
                {
                    smList.Add(getItemAsStatusMood(moodId, useRpc));
                }

                return smList;
            }

            return getItemAsCollection<StatusMood>(id, useRpc, "statusMood");
        }

        public Response<StatusMoodComment> getItemAsStatusMoodCommentsCollection(string id, bool useRpc)
        {
            return getItemAsCollection<StatusMoodComment>(id, useRpc, "entry");
        }

        public Response<Group> getItemAsGroupsCollection(string id, bool useRpc)
        {
            return getItemAsCollection<Group>(id, useRpc, "group");
        }

        public Response<T> getItemAsCollection<T>(string id, bool useRpc, string entryName)
            where T : data.OpenSocialObject
        {
            return OpenSocialJsonParser.parseAsCollection<T>(items[id], useRpc, entryName);
        }

        public T getItemAsObject<T>(string id, string entryName)
            where T : data.OpenSocialObject
        {
            return OpenSocialJsonParser.parseAsObject<T>(items[id], true, entryName);
        }

        public bool isItemEntryAnArray(string id)
        {
            return OpenSocialJsonParser.isEntryArray(items[id]);
        }

        /// <summary> Creates a new entry in items Map with the passed ID as key and JSON object
        /// string as value.
        /// </summary>
        /// <param name="id">Response item ID
        /// </param>
        /// <param name="objectString">JSON object string to associate with the passed ID
        /// </param>
        public void addItem(string id, string objectString)
        {
            items.Add(id, objectString);
        }
    }
}